package com.waijiaojun.tpo.service;

import com.waijiaojun.tpo.entity.*;
import com.waijiaojun.tpo.repository.*;
import com.waijiaojun.tpo.rest.RestClientException;
import com.waijiaojun.tpo.utils.UserUtil;
import com.waijiaojun.tpo.utils.Util;
import com.waijiaojun.tpo.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserCategoryService {

    @Resource
    private UserCategoryDao userCategoryDao;
    @Resource
    private SentencePatternDao sentencePatternDao;
    @Resource
    private CategoryDao categoryDao;
    @Resource
    private ScenarioDao scenarioDao;
    @Resource
    private UserAnswersDao userAnswersDao;
    @Resource
    private VocabularyDao vocabularyDao;
    @Resource
    private UserScenarioProgressDao userScenarioProgressDao;
    @Resource
    private QuestionDao questionDao;
    @Resource
    private QuestionCategoryDao questionCategoryDao;


    public int insert(UserCategory pojo) {
        return userCategoryDao.insert(pojo);
    }

    public int insertSelective(UserCategory pojo) {
        return userCategoryDao.insertSelective(pojo);
    }

    public int insertList(List<UserCategory> pojos) {
        return userCategoryDao.insertList(pojos);
    }

    public int update(UserCategory pojo) {
        return userCategoryDao.update(pojo);
    }

    public List<UserCategoryVo> findCategoryWithUser(String openid) {
        return userCategoryDao.findCategoryWithUser(openid);
    }

    public CategoryDetailsVo findCategoriesDetailsWithUser(String openid, Long categoryId) {
        Category category = categoryDao.findByCategoryId(categoryId);
        if (category == null) {
            throw new RestClientException("无效的分类id:" + categoryId);
        }
        CategoryDetailsVo vo = new CategoryDetailsVo();
        vo.setCategoryid(category.getId());
        vo.setCategoryNameCn(category.getName_cn());
        vo.setCategoryNameEn(category.getName_en());
        vo.setCategoryCoverUrl(category.getCover_url());
        vo.setCategoryVideoUrl(category.getVideo_url());
        List<UserScenarioProgressVo> userScenarioProgressList = userCategoryDao.findUserScenarioProgressWithOpenidAndCategoryId(openid, categoryId);
        vo.setUserScenarioProgressList(userScenarioProgressList);
        return vo;
    }

    public void categoriesClick(String openid, Long categoryId) {
        UserCategory userCategory = userCategoryDao.findByOpenidAndCategoryId(openid, categoryId);
        if (userCategory == null) {
            userCategory = new UserCategory();
            userCategory.setCategoryId(categoryId);
            userCategory.setOpenid(openid);
            userCategoryDao.insertSelective(userCategory);
        }

    }

    // 场景(文章)详情
    public ScenarioDetailVo scenarioDetail(String openid, Long scenarioId) {
        UserScenarioProgress usp = userScenarioProgressDao.findByOpenidAndScenarioId(openid, scenarioId);
        if (usp == null) {
            usp = new UserScenarioProgress();
            usp.setOpenid(openid);
            usp.setScenario_id(scenarioId);
            usp.setScore(0L);
            usp.setQuantity_of_vocabulary(0L);
            userScenarioProgressDao.insertSelective(usp);
        }

        ScenarioDetailVo vo = scenarioDao.findVoById(openid, scenarioId);
        if (vo == null) {
            throw new RestClientException("无效的场景id:" + scenarioId);
        }

        Long question_number = scenarioDao.findQuestionNumberById(scenarioId);//题目数量
        List<UserAnswers> userAnswersList = userAnswersDao.findByScenarioIdAndOpenid(openid, scenarioId);
        Long duration = 0L;//练习总用时，单位秒
        Long question_number_done = 0L;//完成练习题目数量
        Long question_number_done_correct = 0L;//做对题目数量
        Long question_number_done_error = 0L;//做错题目数量
        if (userAnswersList != null) {
            for (UserAnswers ua : userAnswersList) {
                duration += ua.getDuration();
                question_number_done++;
                if (ua.getResult().longValue() == 1) {
                    question_number_done_correct++;
                } else {
                    question_number_done_error++;
                }
            }
        }
        vo.setQuestion_number(question_number == null ? 0L : question_number);
        vo.setDuration(duration);
        vo.setQuestion_number_done(question_number_done);
        vo.setQuestion_number_done_correct(question_number_done_correct);
        vo.setQuestion_number_done_error(question_number_done_error);

        Long vocabulary_number = vocabularyDao.countForScenarioId(openid, scenarioId);//掌握的词汇量
        vo.setVocabulary_number(vocabulary_number == null ? 0L : vocabulary_number);

        // 评分，总分3分
//        Double d = question_number_done_correct/question_number;
//        vo.setScore(Util.calculatorScore(question_number, question_number_done_correct));
        vo.setScore(usp.getScore() == null ? 0 : usp.getScore());
        return vo;
    }

    public void clickButton(String openid, Long number, Long scenarioId) {
        userCategoryDao.clickButton(openid, number, scenarioId);
    }

    // 预习
    public PrepareVo prepare(Long scenarioId) {
        PrepareVo prepareVo = new PrepareVo();
        List<SentencePattern> sentencePatternList = sentencePatternDao.findByScenarioId(scenarioId);// 查询句型
        List<Vocabulary> vocabularyList = vocabularyDao.findByScenarioId(scenarioId);// 查询词汇
        prepareVo.setSentencePatternsList(sentencePatternList);
        prepareVo.setVocabularyList(vocabularyList);
        return prepareVo;
    }

    // 回顾
    public ReviewVo review(Long scenarioId) {
        ReviewVo vo = new ReviewVo();
        Scenario scenario = scenarioDao.findById(scenarioId);
        if (scenario == null) {
            throw new RestClientException("无效的场景id:" + scenarioId);
        }
        vo.setTpo_name(scenario.getTpo_name());
        vo.setArticle_cn(scenario.getArticleCn());
        vo.setArticle_en(scenario.getArticleEn());
        vo.setScenario_name_cn(scenario.getNameCn());
        vo.setScenario_name_en(scenario.getNameEn());
        vo.setArticle_audio_url(scenario.getAudioUrl());
        vo.setCover_url(scenario.getCoverUrl());
        vo.setAudio_url(scenario.getAudioUrl());
        vo.setReview_image_url(scenario.getReview_image_url());

        List<QuestionAndUserAnswerVo> questionListWithUserAnswers = questionDao.findWithUserAnswerByScenarioId(scenarioId, UserUtil.getCurrentUserOpenId());
        vo.setQuestionListWithUserAnswers(questionListWithUserAnswers);

        List<Vocabulary> vocabularyList = vocabularyDao.findByScenarioId(scenarioId);// 查询词汇
        if (vocabularyList != null && vocabularyList.size() > 0) {
            for (Vocabulary v : vocabularyList) {
                vo.getVocabularyList().add(v.getWord());
            }
        }

        // 重点句型
        List<SentencePattern> sentenceList = sentencePatternDao.findByScenarioId(scenarioId);
        if (sentenceList != null && sentenceList.size() > 0) {
            for (SentencePattern sp : sentenceList) {
                vo.getSentenceList().add(sp.getContentEn());
            }
        }

        return vo;
    }

    // 听音频
    public ExecAudioVo execAudio(Long scenarioId) {
        ExecAudioVo vo = new ExecAudioVo();
        Scenario scenario = scenarioDao.findById(scenarioId);
        if (scenario == null) {
            throw new RestClientException("无效的场景id:" + scenarioId);
        }
        vo.setScenario_id(scenario.getId());
        vo.setScenario_name_cn(scenario.getNameCn());
        vo.setScenario_name_en(scenario.getNameEn());
        vo.setScenario_audio_url(scenario.getAudioUrl());
        return vo;
    }

    // 题目
    public List<Question> execQuestion(Long scenarioId) {
        List<Question> questionList = questionDao.findByScenarioId(scenarioId);
        return questionList;
    }

    // 提交答案
    public List<QuestionAndUserAnswerVo> execSaveUserAnswer(String openid, List<UserAnswers> userAnswersList, Long scenarioId) {
        if (StringUtils.isBlank(openid)) {
            throw new RestClientException("无效的openid:" + openid);
        }
        for (UserAnswers ua : userAnswersList) {
            ua.setOpenid(openid);
            if (ua.getQuestionId() == null) {
                throw new RestClientException("题号时间不能为空");
            }
            if (ua.getScenario_id() == null) {
                ua.setScenario_id(scenarioId);
            }
            if (ua.getDuration() == null) {
                throw new RestClientException("题号" + ua.getQuestionId() + "的答题时间不能为空");
            }
            if (ua.getResult() == null || (ua.getResult().longValue() != 0 && ua.getResult().longValue() != 1)) {
                throw new RestClientException("题号" + ua.getQuestionId() + "的答题结果无效");
            }
        }
        // 删除老的用户答案
        List<UserAnswers> oldAnswers = userAnswersDao.findByScenarioIdAndOpenid(openid, scenarioId);
        if (oldAnswers != null && oldAnswers.size() > 0) {
            userAnswersDao.deleteByIds(getIds(oldAnswers));
        }

        // 插入新的答案
        userAnswersDao.insertList(userAnswersList);

        // 计算得分
        Long total = Long.valueOf(userAnswersList.size());
        Long question_number_done_correct = 0L;//做对题目数量
        if (userAnswersList != null) {
            for (UserAnswers ua : userAnswersList) {
                if (ua.getResult().longValue() == 1) {
                    question_number_done_correct++;
                }
            }
        }
        Long score = Util.calculatorScore(total, question_number_done_correct);
        // 保存得分
        UserScenarioProgress usp = userScenarioProgressDao.findByOpenidAndScenarioId(openid, scenarioId);
        usp.setScore(score);
        userScenarioProgressDao.update(usp);

        // 查询文章和问题和用户答案
        List<QuestionAndUserAnswerVo> questionListWithUserAnswers = questionDao.findWithUserAnswerByScenarioId(scenarioId, UserUtil.getCurrentUserOpenId());

        return questionListWithUserAnswers;
    }

    private List<Long> getIds(List<UserAnswers> oldAnswers) {
        List<Long> ids = new ArrayList<>();
        for (UserAnswers ua : oldAnswers) {
            ids.add(ua.getId());
        }
        return ids;
    }

    // 错题统计
    public StatisticsErrorsQuestionResultVo statisticsErrorsQuestion(String openid) {
        StatisticsErrorsQuestionResultVo resultVo = new StatisticsErrorsQuestionResultVo();
        List<StatisticsErrorsQuestionVo> voList = questionCategoryDao.findAllForVo();
        List<StatisticsErrorsQuestionVo> userVoList = userAnswersDao.statistics(openid);
        long total = 0;// 总共错题数量
        for (StatisticsErrorsQuestionVo uvo : userVoList) {
            total += uvo.getError_question_number();
        }

        // 计算百分比
        for (StatisticsErrorsQuestionVo uvo : userVoList) {
            long n = uvo.getError_question_number();
            float percent = 0;
            if (n != 0) {
                percent = (n * 100.0f) / total;
            }
            uvo.setError_question_percent((long) percent);
        }

        for (StatisticsErrorsQuestionVo vo : voList) {
            for (StatisticsErrorsQuestionVo uvo : userVoList) {
                if (vo.getQuestion_category_id() != null && uvo.getQuestion_category_id() != null && vo.getQuestion_category_id().longValue() == uvo.getQuestion_category_id().longValue()) {
                    vo.setError_question_number(uvo.getError_question_number());
                    vo.setError_question_percent(uvo.getError_question_percent());
                }
            }

        }

        resultVo.setData1(voList);

        // 按分类统计错题数量
        List<StatisticsErrorsQuestionGroupByCategoryVo> list = questionCategoryDao.statisticsErrorQuestonGroupByCategory(openid);
        resultVo.setData2(list);
        return resultVo;
    }

    public BootstrapTableDataResponse<Category> findAll(Integer offset, Integer pageSize, String search, String order, String sort) {
        RowBounds rowBounds = new RowBounds(offset, pageSize);
        BootstrapTableDataResponse<Category> response = new BootstrapTableDataResponse<Category>();

        Long total = categoryDao.findAllCount(search);
        response.setTotal(total);

        List<Category> list = categoryDao.findAll(search, order, sort, rowBounds);
        if (list == null) {
            list = new ArrayList<>();
        }
        response.setRows(list);
        return response;
    }

    public void updateCategory(Category category) {
        if (StringUtils.isBlank(category.getScenarioSize())) {
            category.setScenarioSize(null);
        }
        if (StringUtils.isBlank(category.getDescription())) {
            category.setDescription(null);
        }
        categoryDao.update(category);
    }

    public void deleteCategory(Long id) {
        categoryDao.delete(id);
    }
}
